package com.tedu.api.list;

import org.junit.Test;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;

/**
 * 数组：遍历数据    遍历数据第三种：普通for、增强for、Arrays工具类
 * √集合：遍历数据    遍历数据第三种：普通for、增强for、Arrays工具类
 * 保存数据优选：集合---遍历数据优选Iterator迭代器
 * Iterator迭代器       接口----依赖Collection提供方法：iterator()
 *
 * 集合：迭代器的使用方式：问、取、 【不是必须操作】删
 */
public class Collection_IteratorAPI {
    @Test
    public void testIterator(){
        Collection c1=new ArrayList();
        c1.add("one");c1.add("two");c1.add("three");
        /**
         * iterator()方法：获取集合的迭代器---遍历数据
         */
        Iterator it=c1.iterator();
        //迭代器使用：1问---集合中是否存在元素【集合元素不确定】
        /**
         * hasNext()     返回值：boolean
         * 作用：判断集合当中是否还有元素可以遍历，
         *      返回true有元素、false没有元素
         */
        while(it.hasNext()){// 迭代器：问操作--hasNext()
            //2.取---如果集合中存在元素：取出元素--next()
            /**
             * E next()   返回值：E泛型  简单理解：Object
             * 作用：遍历取出元素
             */
            String str=(String) it.next();
            System.out.println("集合迭代器"+str);
        }
    }
    /**
     * 集合三种遍历方式：Iterator迭代器【问、取操作】
     *                普通for【难度、需要查API】    √
     *                增强for【没有难度】          √
     *                开发：选一种使用
     *                遍历同时对集合做元素删除操作--Iterator迭代器
     */
    @Test
    public void testFor(){
        //创建集合
        Collection collection=new ArrayList();
        //需求： 10个元素，普通for增加元素0~9数值
        for(int i=0;i<10;i++){
            collection.add(i);
        }
        System.out.println("打印集合数据"+collection);
        //获取集合中所有的数据-----------------操作：遍历
        // ①使用普通for遍历 collection集合，提醒：查API
        //获取数组元素：int[] arr={1,2,3};     数组名[下标]  arr[1]
        //获取集合元素：List---方法             集合名[下标]  ×
          for(int i=0;i<collection.size();i++){//i 值：拿下标
              System.out.println("普通for输出集合："+((List)collection).get(i));
          }
        //②使用增强for遍历：  语法：for(Integer i:集合名){}
        //                      for(Object i:collection){}
        //collection是顶级集合--存任何数据---Object类型
          for (Object i:collection){
              System.out.println("增强for遍历集合:"+i);
          }

    }
    /**
     * 遍历同时对集合做元素删除操作--Iterator迭代器
     * Iterator迭代器--删除操作【真删元素】
     * remove()        返回值：void
     * 作用：删除迭代器获取的元素【理解：next()取元素之后，删除】
     * Iterator迭代器使用规则：问、取、删
     *
     * 作业：增强for循环，删除testRemove单元测试中集合包含“元旦”元素
     *        作业单元测试名：testHomeWork()
     */

    /**
     * 集合：Iterator 通过迭代--遍历集合--遍历同时删除元素  【推荐】
     *      普通for
     *      增强for
     *      ConcurrentModificationException  并发修改异常
     *      产生原因：增强for底层遍历采用Iterator遍历---迭代器删除元素
     *                                      集合删元素
     *               增强for中删除集合元素的方法用错！
     */
    @Test
    public void testHomeWork(){
        Collection<String> c=new ArrayList();
        c.add("十一");c.add("元旦");c.add("春节");c.add("元宵节");
        //1.创建Iterator迭代器对象---通过集合获取对象
        Iterator<String> it=c.iterator();
        //2.迭代器使用遵从：问、取、删
        while(it.hasNext()){//问：集合中是否有元素 true
            String str=it.next();//取：集合每个元素
            if ("元旦".equals(str)){
              //  it.remove();  迭代器 it  删除  集合元素
                c.remove(str); //删除肯定报错
            }
        }
      /*  for (String str:c){
            if("元旦".equals(str)){ //元旦 判断 集合 “元旦”
                c.remove(str);    //是集合中的元旦，删除
            }
            System.out.println("增强for："+str);
        }
        System.out.println("打印集合："+c);*/
    }
    @Test
    public void testRemove(){
        Collection c=new ArrayList();
        c.add("十一");c.add("元旦");c.add("春节");c.add("元宵节");
        //创建集合Collection---遍历同时删除春节的元素
        System.out.println("Collection集合："+c);
        //1.依赖集合Collection--提供iteration()方法：创建迭代器对象
        Iterator it=c.iterator();
        //2.使用迭代器：问、取、删
        while(it.hasNext()){//问：集合中是否有元素
        //3.获取集合中元素  next() 获取集合中元素，默认类型Object
        String str=(String) it.next();
        //4.删除结合中存在“春节”的元素
            //4.1如果集合当中元素名“春节”--删除
            if("春节".equals(str)){
                it.remove();//next() 拿到元素之后删除操作
            }
        //    c.remove("春节");  //从集合中删除
        }
        System.out.println("由迭代器实现删除元素操作："+c);
    }
    /**
     * 泛型：与集合搭配使用    E element 元素 理解：Object
     * JDK1.5之后推出新特性，集合存任何数据，获取数据非常混乱
     *              对象、整数、小数型  取  Object  知道类型
     * 泛型主要功能是约束集合的类型！
     * 泛型编译器认可的，JVM虚拟机不认可，认为：Object对象
     * 使用泛型的好处：1.约束类型，数据稳定【统一类型】,获取元素无需造型
     *              2.类型；对象---继承以及继承之后方法使用super
     * 语法：
     * Collection<类型：引用类型、基本类型、包装类型>  c=
     * new ArrayList<类型：引用类型、基本类型、包装类型>();
     */
    @Test
    public void testElement(){
        //JDK1.5   泛型写法
        Collection<String> c1=new ArrayList<String>();
        //JDK1.7   泛型写法    建议使用
        Collection<String> c2=new ArrayList<>();
        c2.add("老六");c2.add("老七");c2.add("老八");
        Iterator<String> it=c2.iterator();
        while(it.hasNext()){ //问：存在数据，存在true
            String str=it.next();
        }
        //c2.add(1);c2.add(1.23);
        //c2.add(new Object());
        Collection<Integer> c3=new ArrayList<>();
      //  Collection<Boolean> c4=new ArrayList<Boolean>();

        //泛型定义：？代表：不限制类型  项目非常大--功能
        Collection<?> c4=new ArrayList<>();
      //  c4.add("字符串");c4.add(1);c4.add(1.123);
       //c4.add(new Object());
        c4.add(null);     //只能存没由意义的值：引用类型--默认值：null
    }

    /**
     * 泛型中通配符  ？【任意类型】   的使用
     * ？【任意类型】 extends 父类
     * 【任意类型：父类的所有子类】    --约束--
     */
    @Test
    public void testE(){
        //测试:创建集合---传入参数：引用类型：Apple对象
        Collection<Apple> apples=new ArrayList<>();
        apples.add(new Apple()); //存入apple对象
        TestJob.printFruit(apples);//

        Collection<Orange> Oranges=new ArrayList<>();
        Oranges.add(new Orange());
        TestJob.printFruit(Oranges);//上界限定操作：针对集合


    }
    /**
     *  测试：    父类：Fruit--属性：name 名字 | 方法：获取名称 |构造器
     *                  两个子类：Apple、Orange--构造器：传水果名
     *                  创建TestJob类  泛型  ？ extends 父类
     *                  约束 ----静态的方法printFruit()
     *                约束要求：只能是继承父类的子类才可以使用
     *                  单元测试：testE()测试--约束是否限制成功
     *           实际开发应用中，高级程序员制定！
     */
    public class Fruit{
        private String name;  //私有属性   name  水果名称

        public String getName() {//获取名字
            return name;
        }

        public Fruit(String name) {//有参数构造器
            this.name = name;
        }
    }
    //创建两个子类：Apple和Orange继承Fruit
    class Apple extends Fruit{//Apple a=new Apple();  打印水果名称
        public Apple() { //Apple a=new Apple();
            super("苹果");
        }
    }
    class Orange extends Fruit{
        public Orange() {
            super("橘子");
        }
    }
//创建TestJob类---静态方法printFruit：添加约束：传入类型一定是父类的子类
static class TestJob{           //?【任意类型】 extends Fruit
                             //传入类型必须继承与Fruit父类
        public static void printFruit(Collection<? extends Fruit> fruits){
                //增强for循环：父类Fruit 名称
            for(Fruit fruit:fruits){//获取继承【Apple、Orange】与父类的功能
                System.out.println(fruit.getName());


            }
        }
    }
    //集合重点：Collection常用方法、Iterator迭代器、泛型【超级重点】
    //聊天室    JavaSE   WEB    数据库--JavaWEB【集合】
}
